﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Netfraction
{
    public class ShellInfo
    {
        public static ImageSource GetIcon(string path, bool fileExists)
        {
            ImageSource source = null;
            SHFILEINFO shinfo = new SHFILEINFO();

            Win32.SHGFI flags = fileExists ? Win32.SHGFI.Icon : Win32.SHGFI.Icon | Win32.SHGFI.UseFileAttributes;

            //if (Use32PixelIcon)
            //Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags | Win32.FileInfoFlags.SHGFI_LARGEICON);
            Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), (uint)(flags | Win32.SHGFI.LargeIcon));
            //else
            //    Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags | Win32.SHGFI_SMALLICON);

            Icon fileIcon = Icon.FromHandle(shinfo.hIcon);
            using (MemoryStream memStream = new MemoryStream())
            {
                Bitmap iconBitmap = fileIcon.ToBitmap();
                iconBitmap.Save(memStream, System.Drawing.Imaging.ImageFormat.Png);

                memStream.Seek(0, SeekOrigin.Begin);
                PngBitmapDecoder bitmapDecoder = new PngBitmapDecoder(memStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                source = bitmapDecoder.Frames[0];
                source.Freeze();
            }
            return source;
        }

        public static string GetFileType(string path, bool fileExists)
        {
            SHFILEINFO shinfo = new SHFILEINFO();
            //Win32.FileInfoFlags flags = fileExists ? Win32.SHGFI.TypeName : Win32.SHGFI.TypeName | Win32.SHGFI.UseFileAttributes;
            Win32.SHGFI flags = Win32.SHGFI.TypeName | Win32.SHGFI.UseFileAttributes;
            //Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), flags);
            Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), (uint)flags);
            return shinfo.szTypeName;
        }
    }

    class Win32
    {
        [Flags]
        public enum SHGFI : uint
        {
            /// <summary>get icon</summary>
            Icon = 0x000000100,
            /// <summary>get display name</summary>
            DisplayName = 0x000000200,
            /// <summary>get type name</summary>
            TypeName = 0x000000400,
            /// <summary>get attributes</summary>
            Attributes = 0x000000800,
            /// <summary>get icon location</summary>
            IconLocation = 0x000001000,
            /// <summary>return exe type</summary>
            ExeType = 0x000002000,
            /// <summary>get system icon index</summary>
            SysIconIndex = 0x000004000,
            /// <summary>put a link overlay on icon</summary>
            LinkOverlay = 0x000008000,
            /// <summary>show icon in selected state</summary>
            Selected = 0x000010000,
            /// <summary>get only specified attributes</summary>
            Attr_Specified = 0x000020000,
            /// <summary>get large icon</summary>
            LargeIcon = 0x000000000,
            /// <summary>get small icon</summary>
            SmallIcon = 0x000000001,
            /// <summary>get open icon</summary>
            OpenIcon = 0x000000002,
            /// <summary>get shell size icon</summary>
            ShellIconSize = 0x000000004,
            /// <summary>pszPath is a pidl</summary>
            PIDL = 0x000000008,
            /// <summary>use passed dwFileAttribute</summary>
            UseFileAttributes = 0x000000010,
            /// <summary>apply the appropriate overlays</summary>
            AddOverlays = 0x000000020,
            /// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
            OverlayIndex = 0x000000040,
        }   
         
        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);

    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHFILEINFO
    {
        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    };

}
